﻿using System;
using System.Linq.Expressions;
using System.Windows.Forms;
using CloudShot.Utils;

namespace CloudShot.ViewModels
{
  internal class CheckBoxValues<T>
  {
    public T CheckedValue { get; set; }
    public T UnCheckedValue { get; set; }
  }

  internal interface IPropertyHandler
  {
    event Action<PropertiesFormViewModel> RefreshRequest;
    void SetViewModel(PropertiesFormViewModel viewModel);
  }

  internal class CheckBoxPropertyHandler<T> : PropertyHandlerBase<T>, IPropertyHolder<CheckBox, CheckBoxValues<T>>, IPropertyHandler
  {
    private readonly bool _hasPreviewByHover;
    private readonly ControlHoverHandler<CheckBox, CheckBoxValues<T>> _hoverHandler;

    public event Action<PropertiesFormViewModel> RefreshRequest;

    public CheckBoxPropertyHandler(Expression<Func<PropertiesFormViewModel, T>> expression, CheckBox control, T checkedValue, T unCheckedValue,
                                   bool hasPreviewByHover = true) : base(expression.GetPropertyInfo())
    {
      _hasPreviewByHover = hasPreviewByHover;
      _hoverHandler = new ControlHoverHandler<CheckBox, CheckBoxValues<T>>(control, this, new CheckBoxValues<T>
      {
        CheckedValue = checkedValue,
        UnCheckedValue = unCheckedValue
      });
    }

    protected override void UpdateButtons(T value)
    {
      _hoverHandler.Control.Checked = _hoverHandler.PropertyValue.CheckedValue.Equals(value);
    }

    //TODO almost copy paste from radio buttons
    protected override void InvokeRefreshRequest(PropertiesFormViewModel viewModel)
    {
      var handler = RefreshRequest;
      if (handler != null)
        handler(viewModel);
    }

    #region IPropertyHolder<CheckBox, CheckBoxValues<T>> Implementation

    void IPropertyHolder<CheckBox, CheckBoxValues<T>>.PreviewProperty(CheckBox control, CheckBoxValues<T> previewValue)
    {
      if (!_hasPreviewByHover)
        return;

      if (ViewModel == null)
        return;

      CurrentPreviewValue = previewValue.CheckedValue;
      PropertyInfo.SetValue(ViewModel, CurrentPreviewValue, null);
      InvokeRefreshRequest(ViewModel);
    }

    void IPropertyHolder<CheckBox, CheckBoxValues<T>>.ResetPreviewProperty(CheckBox control)
    {
      if (!_hasPreviewByHover)
        return;

      if (ViewModel == null)
        return;

      CurrentPreviewValue = InitialValue;
      PropertyInfo.SetValue(ViewModel, InitialValue, null);
      InvokeRefreshRequest(ViewModel);
    }

    void IPropertyHolder<CheckBox, CheckBoxValues<T>>.SetProperty(CheckBox control, CheckBoxValues<T> value)
    {
      if (ViewModel == null)
        return;

      T setValue = control.Checked ? value.CheckedValue : value.UnCheckedValue;
      PropertyInfo.SetValue(ViewModel, setValue, null);
      InitialValue = setValue;
      InvokeRefreshRequest(ViewModel);
    }

    #endregion
  }
}